#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
//第七章运算符重载
int gcd(int a, int b){
	a=abs(a);
	b=abs(b);
	while(b){a%=b;swap(a,b);}
	return a;
}
class Rational {
public:
	int fenzi, fenmu;
	Rational() { fenzi = 1; fenmu = 1; }
	Rational(int a, int b) :fenzi{ a }, fenmu{ b } 
	{
		jianhua();
	};
	void jianhua(){
		if(fenzi==0){fenmu=0;return;}
		if(fenmu<0){fenzi=-fenzi;fenmu=-fenmu;}
		int common=gcd(fenzi,fenmu);
		fenzi/=common;
		fenmu/=common;
	}
	Rational operator + (const Rational &b) {
		long long commonfenmu=fenmu*b.fenmu/gcd(fenmu,b.fenmu);
		int newfenzi=fenzi*(commonfenmu/fenmu)+b.fenzi*(commonfenmu/b.fenmu);
	    return Rational(newfenzi,commonfenmu);
	}

	Rational operator - (const Rational &b) {
		long long commonfenmu=fenmu*b.fenmu/gcd(fenmu,b.fenmu);
		int newfenzi=fenzi*(commonfenmu/fenmu)-b.fenzi*(commonfenmu/b.fenmu);
		return Rational(newfenzi,commonfenmu);
	}

	friend Rational operator * (const Rational &a,const Rational &b) {
		return Rational(a.fenzi*b.fenzi,a.fenmu*b.fenmu);
	}
	friend Rational operator / (const Rational &a,const Rational &b) {
		if(b.fenzi==0){cout<<"error"<<endl; }
		return Rational(a.fenzi*b.fenmu,a.fenmu*b.fenzi);
	}
	
	Rational& operator ++() {//返回的是this指针所以用&
		fenzi += fenmu;
		jianhua();
		return *this;
	}

	Rational&  operator=(const Rational &other)
	{   if(this != &other)
       {fenzi=other.fenzi;
	   fenmu=other.fenmu;}
	   return *this;
	}
	
	Rational& invert(){
		int temp =fenzi;
		fenzi=fenmu;
		fenmu=temp;
		jianhua();
		return *this;
	}

   friend ostream& operator<<(ostream& out,const Rational& r){
	if(r.fenmu==1){
		out<<r.fenzi;
	}
	else{out<<r.fenzi<<"/"<<r.fenmu;}
	return out;
   }
	
};
 
int main() {
   int f1_fenzi,f1_fenmu;
   cin>>f1_fenzi>>f1_fenmu;
   Rational R1(f1_fenzi,f1_fenmu);
   int f2_fenzi,f2_fenmu;
   cin>>f2_fenzi>>f2_fenmu;
   Rational R2(f2_fenzi,f2_fenmu);

  cout<<R1+R2<<endl;
  cout<<R1-R2<<endl;
  cout<<R1*R2<<endl;
  cout<<R1/R2<<endl;
 
  Rational R1_f=R1;
  Rational R2_f=R2;
  cout << ++R1_f << " " << ++R2_f << endl;
  cout<<R1.invert()<<" "<<R2.invert()<<endl;
  system("pause");
  return 0;
}

//二、第八章多态
class Distance {
public:
	int x, y;
	Distance(int a = 0, int b = 0)
	{
		if (a >= 0 && a <= 40000 && b >= 0 && b <= 40000) {
			x = a; y = b;
		}
		else { cout << "error" << endl; }
	};
	virtual int distance(const Distance&b) = 0;
};

class ManhattanDistance :public Distance {
public:
	ManhattanDistance(int x=0, int y=0) :Distance(x, y) {};
    int distance(const Distance &b) override//明确表示该函数是重写基类的虚函数。
	{
		int d = abs(x - b.x) + abs(y - b.y);
		return d;
	}
   
};

class EuclideanDistance:public Distance {
public:
	EuclideanDistance(int x=0, int y=0):Distance(x, y) {};
	  int distance( const Distance& b) override
	  {
		  int d = (x - b.x)*(x - b.x) + (y - b.y)*(y - b.y);
		  return d;
	  }
};

int main() {
	int ax, ay;
	int bx, by;
	cin >> ax >> ay >> bx >> by;
	ManhattanDistance a(ax, ay);
	EuclideanDistance b(bx, by);
	Distance * p;
	p=&a;
	cout<<p->distance(b)<<" ";
	p=&b;
	cout << p->distance(a) << endl;


	

}

//三、第八章继承
class String {
public:
	string s ;//为什么使用string类而不是字符数组？
//string 提供了很多便利的功能（如 length()、insert()、erase() 等）
//string 自动管理内存，不需要手动处理字符串长度和 \0 结尾
//string 更安全，不容易发生缓冲区溢出
//如果要用字符数组：
//需要手动管理数组大小
//需要手动处理字符串结尾的 \0
//需要自己实现插入、删除等操作
//这就是为什么在"法二"中我们使用了字符数组，但需要写更多的代码
	String(const char *str = "1234567890") :s{ str } {};
	size_t len() { return s.length(); }
};

class EditableString:public String{
public:
  EditableString(const char *str="1234567890"):String(str){}
  //const保证传入的字符串字面量是常量，
  //且c++中字符串字面量是常量，不能直接赋值给非常量指针
  void insert_ch(int num, char ch){
	if(num>=1 && num<=s.length()+1){
       //1 2 3 4 5 6 7 8 9 0
	   //1 2 3 4 5 6 7 8 9 10 11
      s.insert(num-1,1,ch);//要插入的起始位置，字符数，和内容
 //num-1是因为题目要求的位置是从1开始计数（第1个位置，第2个位置...）
 //而 string 的索引是从0开始计数（索引0，索引1...）
	}  }

	void delete_ch(int num){
   if(num>=1&&num<=s.length()){
	s.erase(num-1,1);//要删除的起始位置，要删除的字符数
   }
	}

	void replace_ch(int num,char ch){
		if(num>=1&&num<=s.length()){
	    s[num-1]=ch; //s[num-1] 不是直接访问数组，而是调用了 string 类重载的 [] 运算符
//s[num-1] 实际上是 string 类重载了 [] 运算符，让我们可以像访问数组一样访问字符串中的字符。
   }
	}
};
 int main(){
	EditableString mystring;
	char type;
	int num;
	char ch;
	
	while(cin>>type){
		if(type=='i'){
			cin>> num>>ch;
			mystring.insert_ch(num,ch);
		}
		else if(type=='d'){
			cin>>num;
			mystring.delete_ch(num);
		}
		else if(type=='r'){
          cin>>num>>ch;
		  mystring.replace_ch(num,ch);
		}
		else{
			break;
		}
		cout<<mystring.s<<endl;
	}
	system("pause");
	return 0;
 }

//法二：
class String{
public: char str[100];
int length;
String (const char*ch="1234567890"){

	 length=0;
	while(ch[length]!='\0'){str[length]=ch[length];
	length++;}
	str[length] = '\0';//是否char*默认值不含有\0，
}

int len()const{return length;}

friend ostream& operator<<(ostream& os,const String&s)
{
	os<<s.str;
	return os;//因为返回值是ostream
}
};

class EditableString:public String{
	public:
	EditableString(const char*ch="1234567890"):String(ch){};

	void insert(int num,char c){
		if(num<1 || num>length+1){
			return;//结束当前函数的执行，直接回到调用这个函数的地方继续执行，也就是main中的cout<<str<<endl;
		}

		for(int i=length;i>=num-1;i--)  
		//1 2 3 4 5 6 7 8 9 0 \0
		//0 1 2 3 4 5 6 7 8 9 10
		{
			str[i+1]=str[i];
		}

		str[num-1]=c;
		length++;
		str[length]='\0';
	}

	void delete_my(int num){
      if(num<1 || num>length){return;}
	  for(int i=num-1;i<length;i++) {
		str[i]=str[i+1];
	  }
	  length--;
	  str[length]='\0';
	}

	void replace(int num,char c){
		if(num<1 || num>length+1){
			return;
		}
		str[num-1]=c;
	}
};

int main(){
	EditableString str;
	char type;
	int num;
	char ch;
while(cin>>type){
	if(type=='i'){
		cin>>num>>ch;
		str.insert(num,ch);
		cout<<str<<endl;
	}
	else if(type=='d'){
		cin>>num;
		str.delete_my(num);
		cout<<str<<endl;
	}
	else if(type=='r'){
		cin>>num>>ch;
		str.replace(num,ch);
		cout<<str<<endl;
	}
	else {break;
	//这里用return和break区别：break是跳出while循环，继续执行return 0；
	//如果是return的话，会跳出main函数，即程序立即结束，不会执行到return 0；
	}
}
	return 0;
}

//第九章函数模板
template<class T>void  Print(T* p, int n) {
	for (int i = 0; i < n; i++) {
		cout << *(p + i) << " ";
	}
}

template<class T> void Gtlever(T* p, int n, T lever) {
	int count = 0;//大于lever的个数
	T temp;
	for (int i = 0; i < n;i++) {
		if(*(p + i) > lever) {
			 temp=p[i];
			 p[i]=p[count];
			 p[count] = temp;
			count++;
		}
		//基本思路：
			//使用一个指针 count 指向当前应该放置大于 lever 元素的位置
			//遍历数组，找到大于 lever 的元素就放到 count 位置
			//count 位置之前的元素都是已经处理好的大于 lever 的元素
	}
	Print(p, count);
}

int main() {
	string s=" ";
	int length,n;
	cin >> s >> length >> n;
	if (s == "int") {
		int a[100];
		int lever;
		for (int i = 0; i < length; i++) {
			cin >> a[i];
		}
		cin >> lever;
		Gtlever(a, n, lever);//函数模板不像类模板实例化要<int>
	}
	else if (s == "char") {
		char a[100];
		char lever;
		for (int i = 0; i < length; i++) {
			cin >> a[i];
		}
		cin >> lever;
		Gtlever(a, n, lever);
	}
	else if (s == "float") {
		float a[100];
		float lever;
		for (int i = 0; i < length; i++) {
			cin >> a[i];
		}
		cin >> lever;
		Gtlever(a, n, lever);
	}
	return 0;
}

//类模板和元素排序
template<typename T>
class shuzu {
public:
	T* arr;
	int size;

	shuzu(int n) { size = n; arr = new T[n]; };
	~shuzu() { delete[]arr; }

	void input() {
		for (int i = 0; i < size; i++) {
			cin >> arr[i];
		}
	}
	void paixu(int n) {
		for (int i = 0; i < size - 1; i++) {
			//j从1开始的话会在每一轮i循环中都跳过前面i个元素的比较
			for (int j = 0; j < size - 1 - i; j++) {
				if (arr[j] > arr[j + 1]) {
					T temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}

		for (int i = 0; i < size; i++) {
			cout << arr[i] << " ";
		}
		cout << endl;
	}
};

int main() {
	int x,y,z;
	cin >> x;
	shuzu<int> obj1(x);
	obj1.input();
	obj1.paixu(x);
	cin>>y;
	shuzu<char>obj2(y);
	obj2.input();
	obj2.paixu(y);
	cin>>z;
	shuzu<string>obj3(z);
	obj3.input();
	obj3.paixu(z);
	
	return 0;
}